﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include "GcmpDatabase.h"
#include "RawMemory.h"
#include "GbmpTypeDefs.h"
#include "NdbObjectMemoryModelNode.h"

namespace gcmp
{
    class ClassId;
    class INdbObjectMemoryModelNodeVisitor;

    //////////////////////////////////////////////////////////////////////////
    class GCMP_DATABASE_EXPORT NdbObjectMemoryModelLeafNode : public NdbObjectMemoryModelNode
    {
        CANNOT_COPY_OR_ASSIGN(NdbObjectMemoryModelLeafNode)
        DEFINE_CAST_DERIVED(gcmp::NdbObjectMemoryModelLeafNode, gcmp::NdbObjectMemoryModelNode)
    public:
        NdbObjectMemoryModelLeafNode(const ClassId & classId, UInt32 version,
            UInt64 dataSize = 0,
            IntOrFloatType intOrFloatType  = IntOrFloatType::UnKnown,
            IntBaseType intBaseType = IntBaseType::UnKnown
        );

        const RawMemory& GetRawMemory() const { return m_rawMemory; }
        RawMemory& GetRawMemoryForWrite() { return m_rawMemory; }

        IntOrFloatType GetIntOrFloatType() const { return m_intOrFloatType; }
        void SetIntOrFloatType(IntOrFloatType intOrFloatType) { m_intOrFloatType = intOrFloatType; }

        IntBaseType GetIntBaseType() const { return m_intBaseType; }
        void SetIntBaseType(IntBaseType intBaseType) { m_intBaseType = intBaseType; }

        virtual NdbObjectMemoryModelNodeType GetType() const override { return NdbObjectMemoryModelNodeType::Leaf; }

        virtual bool IsLeaf() const override { return true; }

        virtual UInt64 GetDataSize() const override { return m_rawMemory.GetSize(); }

        virtual const void * GetData() const override { return m_rawMemory.GetStartAddress(); }

        virtual void * GetDataForWrite() override { return m_rawMemory.GetStartAddress(); }

        virtual void Accept(INdbObjectMemoryModelNodeVisitor * visitor) override;

        // 对比两个节点是否相同，返回值表示是否继续比较，对叶子节点来说，该值总是true。
        virtual bool Compare(
            const NdbObjectMemoryModelNode& base,
            const std::vector<std::pair<std::wstring, std::wstring>>& attributes,
            const NdbElementExportOrCompareOptions& options,
            int level,
            bool & areEqual,
            bool reportNotEqual,
            std::wostringstream& woss
        ) const override;

        std::wstring DataAsWString() const;

    public:
        void* operator new(std::size_t count);
        void operator delete(void* ptr);

    private:
        RawMemory m_rawMemory;

        IntOrFloatType m_intOrFloatType;
        IntBaseType m_intBaseType;
    };
}
